"""
Telnet (TCP/IP protocol stack)

http://support.microsoft.com/kb/231866
"""
from construct import *
from construct.text import *


command_code = Enum(Byte("code"),
    SE = 240,                       # suboption end
    NOP = 241,                      # no-op
    Data_Mark = 242,                #
    Break = 243,                    # 
    Suspend = 244,                  #
    Abort_output = 245,             #
    Are_You_There = 246,            #
    Erase_Char = 247,               # 
    Erase_Line = 248,               # 
    Go_Ahead = 249,                 # other side can transmit now
    SB = 250,                       # suboption begin  
    WILL = 251,                     # send says it will do option
    WONT = 252,                     # send says it will NOT do option
    DO = 253,                       # sender asks other side to do option
    DONT = 254,                     # sender asks other side NOT to do option
    IAC = 255,                      # interpretr as command (escape char)
)

option_code = Enum(Byte("option"),
    TRANSMIT_BINARY = 0,
    ECHO = 1,
    RECONNECTION = 2,
    SUPPRESS_GO_AHEAD = 3,
    APPROX_MESSAGE_SIZE_NEGOTIATION = 4,
    STATUS = 5,
    TIMING_MARK = 6,
    RCTE = 7,
    OUTPUT_LINE_WIDTH = 8,
    OUTPUT_PAGE_SIZE = 9,
    NAOCRD = 10,
    NAOHTS = 11,
    NAOHTD = 12,
    NAOFFD = 13,
    NAOVTS = 14,
    NAOVTD = 15,
    NAOLFD = 16,
    EXTENDED_ASCII = 17,
    LOGOUT = 18,
    BM = 19,
    DATA_ENTRY_TERMINAL = 20,
    SUPDUP = 21,
    SUPDUP_OUTPUT = 22,
    SEND_LOCATION = 23,
    TERMINAL_TYPE = 24,
    END_OF_RECORD = 25,
    TUID = 26,
    OUTMRK = 27,
    TTYLOC = 28,
    TELNET_3270_REGIME = 29,
    X3_PAD = 30,
    NAWS = 31,
    TERMINAL_SPEED = 32,
    REMOTE_FLOW_CONTROL = 33,
    LINEMODE = 34,
    X_DISPLAY_LOCATION = 35,
    ENVIRONMENT_OPTION = 36,
    AUTHENTICATION = 37,
    ENCRYPTION_OPTION = 38,
    NEW_ENVIRONMENT_OPTION = 39,
    TN3270E = 40,
    XAUTH = 41,
    CHARSET = 42,
    RSP = 43,
    COM_PORT_CONTROL_OPTION = 44,
    TELNET_SUPPRESS_LOCAL_ECHO = 45,
    TELNET_START_TLS = 46,
    _default_ = Pass,
)

class LookaheadAdapter(Adapter):
    def _encode(self, obj, context):
        if obj == "\xff":
            obj = "\xff\xff"
        return obj
    def _decode(self, (this, next), context):
        if this == "\xff":
            if next == "\xff":
                return "\xff"
            else:
                raise ValidationError("IAC")
        else:
            return this

def TelnetData(name):
    return StringAdapter(
        GreedyRange(
            LookaheadAdapter(
                Sequence(name, 
                    Char("data"), 
                    Peek(Char("next")),
                )
            )
        )
    )

telnet_suboption = Struct("suboption",
    option_code,
    TelnetData("parameters"),
)

telnet_command = Struct("command",
    Literal("\xff"),
    command_code,
    Switch("option", lambda ctx: ctx.code,
        {
            "WILL" : option_code,
            "WONT" : option_code,
            "DO" : option_code,
            "DONT" : option_code,
            "SB" : telnet_suboption,
        },
        default = Pass,
    ),
)

telnet_unit = Select("telnet_unit", 
    HexDumpAdapter(TelnetData("data")),
    telnet_command,
)

telnet_session = Rename("telnet_session", GreedyRange(telnet_unit))


if __name__ == "__main__":
    # note: this capture contains both the client and server sides
    # so you'll see echos and stuff all mingled. it's not Construct's
    # fault, i was just too lazy to separate the two.
    cap1 = (
    "fffd25fffb25fffa2501fff0fffa25000000fff0fffb26fffd18fffd20fffd23fffd27"
    "fffd24fffe26fffb18fffb1ffffc20fffc23fffb27fffc24fffd1ffffa2701fff0fffa"
    "1801fff0fffa1f009d0042fff0fffa2700fff0fffa1800414e5349fff0fffb03fffd01"
    "fffd22fffb05fffd21fffd03fffb01fffc22fffe05fffc21fffe01fffb01fffd06fffd"
    "00fffc010d0a7364662e6c6f6e65737461722e6f726720287474797239290d0a696620"
    "6e65772c206c6f67696e20276e657727202e2e0d0a0d0a6c6f67696e3a20fffd01fffc"
    "06fffb006e6e657765770d0a0d0a0d0a4c617374206c6f67696e3a2054687520446563"
    "2032312032303a31333a353320323030362066726f6d2038372e36392e34312e323034"
    "2e6361626c652e3031322e6e65742e696c206f6e2074747972760d0a0d0a596f752077"
    "696c6c206e6f7720626520636f6e6e656374656420746f204e455755534552206d6b61"
    "636374207365727665722e0d0a506c65617365206c6f67696e20617320276e65772720"
    "7768656e2070726f6d707465642e0d0a0d0a5b52455455524e5d202d2054484953204d"
    "41592054414b452041204d4f4d454e54202e2e201b5b481b5b4a547279696e67203139"
    "322e39342e37332e32302e2e2e0d0a436f6e6e656374656420746f206f6c2e66726565"
    "7368656c6c2e6f72672e0d0a4573636170652063686172616374657220697320276f66"
    "66272e0d0a0d0a7364662e6c6f6e65737461722e6f726720287474797033290d0a6966"
    "206e65772c206c6f67696e20276e657727202e2e0d0a0d0a6c6f67696e3a206e6e6577"
    "65770d0a0d0a0d0a4c617374206c6f67696e3a20546875204465632032312032303a30"
    "343a303120323030362066726f6d207364662e6c6f6e65737461722e6f7267206f6e20"
    "74747970390d0a1b5b481b5b4a57656c636f6d6520746f207468652053444620507562"
    "6c69632041636365737320554e49582053797374656d202d204573742e20313938370d"
    "0a596f75206172652074686520333735746820677565737420746f6461792c206c6f67"
    "67656420696e206f6e2032312d4465632d30362032303a31353a32332e0d0a0d0a4172"
    "6520796f75207573696e672057696e646f777320324b206f722058503f2028592f4e29"
    "200d0a202020202020202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d"
    "2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a2020202020207c20494d504f52"
    "54414e54212020504c4541534520524541442054484953205645525920434152454655"
    "4c4c59207c0d0a202020202020202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d"
    "2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d0d0a0d0a54686572652069"
    "7320612062756720696e207468652057696e646f777328746d292032303030202f2058"
    "502054454c4e455420636c69656e742077686963680d0a63617573657320697420746f"
    "2073656e642061203c43523e3c4c463e2028646f75626c652072657475726e29206279"
    "2064656661756c742e202049660d0a796f7520617265207573696e672057696e646f77"
    "7328746d292054454c4e455420796f75204d55535420636f7272656374207468697320"
    "5249474854204e4f570d0a696e206f7264657220746f20434f4e54494e55452e202050"
    "6c656173652074616b652074686520666f6c6c6f77696e6720342073746570733a0d0a"
    "0d0a2020312e202045534341504520746f207468652054454c4e45543e2070726f6d70"
    "74206279207072657373696e67205b4354524c5d207769746820796f7572205d206b65"
    "790d0a2020322e2020417420796f75722054454c4e45543e2070726f6d707420747970"
    "653a202027756e7365742063726c66270d0a20202020202028446f206e6f7420747970"
    "652027717569742720616674657220746869732073746570290d0a2020332e20205468"
    "656e20707265737320796f7572205b454e5445525d206b657920545749434520746f20"
    "72657475726e20746f205344460d0a2020342e20205479706520276d6b616363742720"
    "746f2063726561746520796f7572206e657720534446206163636f756e740d0a0d0a41"
    "6e20616c7465726e61746976652054454c4e455420636c69656e743a2020687474703a"
    "2f2f736466312e6f72672f74656c6e65740d0a0d0a46455020436f6d6d616e643a206d"
    "6d6b6b61616363636374740d0d0a1b5b481b5b4a0d0a504c4541534520524541442054"
    "484953204341524546554c4c593a0d0a0d0a596f75206172652061626f757420746f20"
    "637265617465206120554e4958207368656c6c206163636f756e742e20205468697320"
    "6163636f756e74206d617920626520756e6c696b650d0a616e797468696e6720796f75"
    "2776652075736564206265666f72652e20205765207572676520796f7520746f206361"
    "726566756c6c79207265616420616c6c2074686520746578740d0a646973706c617965"
    "64206f6e20796f7572207465726d696e616c2c2061732069742077696c6c2061696465"
    "20796f7520696e20796f7572206c6561726e696e672e0d0a576520616c736f20656e63"
    "6f757261676520796f7520746f2074727920616c6c2074686520636f6d6d616e647320"
    "617661696c61626c65207769746820796f7572206e65770d0a6163636f756e742e2020"
    "546865726520617265206d616e79207479706573206f662067616d65732c206170706c"
    "69636174696f6e7320616e64207574696c69746965730d0a796f752077696c6c206265"
    "2061626c6520746f20696e7374616e746c792072756e20696e206a7573742061206665"
    "77206d6f6d656e74732e2020496620796f75206172650d0a6c6f6f6b696e6720666f72"
    "206120706172746963756c617220636f6d6d616e64206f722076657273696f6e206f66"
    "206120636f6d6d616e64207468617420776520646f206e6f740d0a686176652c207468"
    "65726520617265207761797320746f2072657175657374207468617420697420626520"
    "696e7374616c6c65642e2020576520616c736f206f666665720d0a4449414c55502061"
    "636365737320696e207468652055534120616e642043616e6164612077686963682079"
    "6f752077696c6c2062652061626c6520746f206c6561726e2061626f75740d0a73686f"
    "72746c792e202042652070617469656e742c2072656164207768617420697320646973"
    "706c61796564202d204578706c6f726520616e6420456e6a6f79210d0a0d0a5b524554"
    "55524e5d0d0d0a0d0a46697273742c20796f75206e65656420746f2063686f6f736520"
    "61204c4f47494e2e202041204c4f47494e20616c6c6f777320796f7520746f204c4f47"
    "20494e0d0a746f207468652073797374656d2e2020596f7572204c4f47494e2063616e"
    "206265203120746f2038206368617261637465727320696e206c656e67746820616e64"
    "0d0a63616e20626520636f6d706f736564206f6620616c706861206e756d6572696320"
    "636861726163746572732e0d0a0d0a5768617420776f756c6420796f75206c696b6520"
    "746f2075736520666f7220796f7572206c6f67696e3f20737365626562756c756c6261"
    "62610d0d0a0d0a436f6e67726174756c6174696f6e732c20796f75277665207069636b"
    "6564206120434c45414e20757365722069642e20205768617420646f65732074686973"
    "206d65616e3f0d0a576520706572666f726d206461696c7920617564697473206f6e20"
    "6f7572206d61696c73657276657220776869636820616c6c6f777320757320746f2063"
    "6865636b206f6e20617474656d7074730d0a6f6620656d61696c2064656c6976657279"
    "20666f72206e6f6e2d6578697374656e74206c6f67696e732c206c696b652027736562"
    "756c6261272e202049662027736562756c626127207761730d0a746172676574746564"
    "20666f7220656d61696c2c20697420776f756c64206c696b656c792068617665206265"
    "656e20554345206f72207370616d2e2020486f77657665722c2074686572650d0a6861"
    "7665206265656e204e4f20617474656d70747320746f20656d61696c2027736562756c"
    "6261407364662e6c6f6e65737461722e6f72672720696e207468652070617374203234"
    "3020646179732c0d0a7768696368206d65616e732069742069732061205350414d2046"
    "524545206c6f67696e2e2020506c656173652070726f7465637420697420616e642065"
    "6e6a6f79210d0a0d0a636f6e74696e75653f20287965732f6e6f29207965730d796573"
    "0d0a1b5b481b5b4a1b5b3f31681b3d1b5b36363b31481b5b4b0d0a0d0a2a2a6c696d69"
    "746174696f6e7320616e6420706f6c6963792a2a0d0a20205f5f5f5f5f5f5f5f5f5f5f"
    "5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f"
    "5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f0d0a0d0a546865"
    "20534446205075626c69632041636365737320554e49582053797374656d2c20612035"
    "303128632937206e6f6e2d70726f66697420636f72706f726174696f6e2c0d0a726573"
    "65727665732074686520726967687420746f2064656e792061636365737320746f2061"
    "6e796f6e65207265676172646c6573732069662074686520757365720d0a686173206d"
    "616465206120646f6e6174696f6e206f722070616964206d656d626572736869702064"
    "7565732e2020496620612075736572277320616374697669746965730d0a6172652069"
    "6e74657266657272696e67207769746820616e6f746865722075736572206f72207573"
    "65727320286f6e20746869732073797374656d206f72206f6e0d0a616e6f7468657229"
    "20746865207573657220696e207175657374696f6e2077696c6c206861766520746865"
    "6972206163636f756e7420616363657373206c696d697465640d0a6f7220706f737369"
    "626c792072656d6f7665642e20205370616d6d696e67206f6620616e7920736f727420"
    "6973206e6f74207065726d697474656420616e6420776f756c640d0a726573756c7420"
    "696e206163636f756e742072656d6f76616c2e2020496c6c6567616c20616374697669"
    "746965732074686174206163746976656c7920696e766f6c7665200d0a534446202869"
    "64206573742c207573696e672053444620746f2072756e20637261636b206f7220666f"
    "72206775657373696e672070617373776f72647320616e642f6f720d0a74726164696e"
    "6720636f70797269676874656420776f726b292077696c6c206d6f7374206c696b656c"
    "7920726573756c7420696e206163636f756e742072656d6f76616c2e0d0a0d0a546865"
    "20534446205075626c69632041636365737320554e49582053797374656d206d616b65"
    "73206e6f2067756172616e7465657320696e207468652072656c696162696c6974790d"
    "0a6f7220707265736572766174696f6e206f66206163636f756e742061636365737369"
    "62696c6974792c20656d61696c2073656e74206f722072656365697665642c0d0a6669"
    "6c65732075706c6f61646564206f722063726561746564206279206f6e6c696e652065"
    "646974696e67206f7220636f6d70696c6174696f6e2e2020546861740d0a6265696e67"
    "20736169642c2064617461206c6f73732073686f756c64206f6e6c79206f6363757220"
    "647572696e67206120636174617374726f706869632068617264776172650d0a666169"
    "6c75726520696e20776869636820637269746963616c2066696c657320776f756c6420"
    "626520726573746f7265642066726f6d20746170652061726368697665732e200d0a0d"
    "0a4d656d62657273206f662074686520534446205075626c6963204163636573732055"
    "4e49582053797374656d2061726520657870656374656420746f20636f6e647563740d"
    "0a7468656d73656c76657320696e20616e20617070726f70726961746520616e642072"
    "6561736f6e61626c65206d616e6e6572207768656e207573696e67206f757220666163"
    "696c69746965732e0d0a0d0a4c69666574696d652041525041206d656d626572736869"
    "70206973206261736564206f6e20746865206c69666574696d65206f66205344462c20"
    "6e6f74206f66207468650d0a7573657220616e64206973206e6f6e2d7472616e736665"
    "7261626c652e20205344462068617320657869737465642073696e6365203139383720"
    "616e6420776974680d0a796f757220737570706f7274206974206a757374206d696768"
    "74206f7574206c69766520796f752e203b2d290d0a2020200d0a416e7920696c6c6567"
    "616c206163746976697469657320776869636820696e636c756465732c206275742063"
    "65727461696e6c792069736e2774206c696d6974656420746f0d0a7370616d6d696e67"
    "2c20706f7274666c6f6f64696e672c20706f72747363616e6e696e672c206972632062"
    "6f7473206f7220756e617474656e6465642070726f6365737365730d0a696e74656e64"
    "6564206173206120626f742c20656e6372797074696f6e20637261636b696e672c2075"
    "6e617574686f726973656420636f6e6e656374696f6e7320746f0d0a72656d6f746520"
    "686f73747320616e6420616e7920736f7274206f66207363616d2063616e207265616c"
    "6c79206e6f7420626520746f6c65726174656420686572652e0d0a5768793f20426563"
    "6175736520746865726520617265206d616e792068657265206f6e2074686973207379"
    "7374656d20746861742063616e207375666665722066726f6d0d0a7468697320736f72"
    "74206f662061627573652e2020496620796f752077616e7420746f2075736520534446"
    "2c20796f75207265616c6c79206861766520746f20636172650d0a61626f7574207468"
    "69732073797374656d20616e64207468652070656f706c6520686572652e2020496620"
    "796f7520646f6e27742077616e7420746f20636172652c207468656e0d0a796f752072"
    "65616c6c792073686f756c646e2774207573652074686973207265736f757263652e0d"
    "0a1b5b36363b31481b5b4b1b5b3f316c1b3e0d0a49206167726565207769746820796f"
    "757220706f6c69637920616e642061636365707420697420287965732f6e6f293a2079"
    "79657365730d0d0a0d0a4279206167726565696e6720616e6420616363657074696e67"
    "206f757220706f6c69637920776520747275737420796f7520746f0d0a666f6c6c6f77"
    "2069742e20205468616e6b20796f7520616e6420626520726573706f6e7369626c6521"
    "0d0a0d0a5b52455455524e5d0d0d0a1b5b481b5b4a534556454e20564552592053494d"
    "504c45205155455354494f4e533a0d0a0d0a506c656173652070726f76696465207468"
    "6520666f6c6c6f77696e6720696e666f726d6174696f6e2e2020596f757220686f6e65"
    "737479206973207265717565737465640d0a617320697420697320637269746963616c"
    "20696e206d61696e7461696e696e672074686520696e74656772697479206f66206f75"
    "722073797374656d2e20204e65770d0a6163636f756e7473207769746820626f677573"
    "20696e666f726d6174696f6e206d617920626520707572676564202a776974686f7574"
    "2a207761726e696e672e0d0a0d0a4354524c2d552077696c6c20636c65617220696e70"
    "7574202e2e0d0a0d0a596f75722046756c6c204e616d653a202020202066666f6f6f6f"
    "626261617272085e48085e4808080808080808085e485e485e485e485e485e485e485e"
    "48035e43035e4315082008082008082008082008082008082008082008082008082008"
    "0820080820080820080820080820080820080820080820080820080820080820080820"
    "08082008082008082008082008082008082008082008082008082008"
    ).decode("hex")
    print telnet_session.parse(cap1)












































